package com.hl.toolkit.admin.system.controller;

import com.tycoin.common.bean.BaseResult;
import com.tycoin.common.bean.jstree.JsTreeBean;
import com.tycoin.common.controller.AbstractController;
import com.tycoin.common.utils.BeanInfoUtil;
import com.tycoin.system.slaveentity.Menu;
import com.tycoin.system.slaveentity.Role;
import com.tycoin.system.slaverepository.MenuRepository;
import com.tycoin.system.slaverepository.RoleRepository;
import com.tycoin.system.slaverservice.MenuService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = {"/system/menu/"})
public class MenuController extends AbstractController {

    @Autowired
    private MenuService menuService;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private RoleRepository roleRepository;

    @RequiresPermissions("system:menu:view")
    @RequestMapping(value = {""})
    public String list(Model model) {
        List<Menu> menuList = menuService.findSortMenu();
        model.addAttribute("menuList", menuList);
        return "system/menu/list";
    }

    @RequiresPermissions("system:menu:add")
    @RequestMapping(value = {"add/{type}"}, method = RequestMethod.GET)
    public String toAdd(Model model, @PathVariable("type") Integer type) {
        Menu menu = new Menu();
        menu.setType(type);
        model.addAttribute("menu", menu);
        return "system/menu/edit";
    }

    @RequiresPermissions("system:menu:add")
    @RequestMapping(value = {"add"}, method = RequestMethod.POST, consumes = "application/json; charset=UTF-8", produces = "application/json; charset=UTF-8")
    @ResponseBody
    public BaseResult add(@RequestBody Menu paramMenu) {
        return edit(null, paramMenu);
    }

    @RequiresPermissions("system:menu:edit")
    @RequestMapping(value = {"{id}/edit"}, method = RequestMethod.GET)
    public String toEdit(Model model, @PathVariable("id") Long id) {
        Menu menu = menuRepository.findOne(id);
        model.addAttribute("menu", menu);
        return "system/menu/edit";
    }

    @RequiresPermissions("system:menu:edit")
    @RequestMapping(value = {"{id}/edit"}, method = RequestMethod.POST, consumes = "application/json; charset=UTF-8", produces = "application/json; charset=UTF-8")
    @ResponseBody
    public BaseResult edit(@PathVariable("id") Long id, @RequestBody Menu paramMenu) {
        Menu menu = null;
        if (null == id) {
            menu = paramMenu;
        } else {
            menu = menuRepository.findOne(id);
            BeanInfoUtil.bean2bean(paramMenu, menu, "type,parentId,name,href,icon,sort,permission");
        }
        menuRepository.save(menu);
        return new BaseResult();
    }

    @RequiresPermissions("system:menu:delete")
    @RequestMapping(value = {"{id}/delete"}, produces = "application/json; charset=UTF-8")
    @ResponseBody
    public BaseResult delete(@PathVariable("id") Long id) {
        Menu menu = menuRepository.findOne(id);
        menuService.delete(menu);
        return new BaseResult();
    }

    @RequiresPermissions("system:menu:view")
    @RequestMapping(value = "{id}/")
    public String view(Model model, @PathVariable("id") Long id) {
        Menu menu = menuRepository.findOne(id);
        model.addAttribute("menu", menu);
        return "system/menu/view";
    }

    private List<JsTreeBean> getNodeList(boolean showPermission, Long roleId, Long filterMenuId) {
        List<Menu> menuList = null;
        if (roleId != null && roleId > 0) {
            Role role = roleRepository.findOne(roleId);
            if (role != null) {
                menuList = role.getMenuList();
            }
        }

        List<JsTreeBean> nodeList = menuService.findJsTreeMenu(showPermission, filterMenuId, menuList);
        return nodeList;
    }

    @RequestMapping(value = {"getTree"}, method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public List<JsTreeBean> getTree(@RequestParam(value = "showPermission", required = false) boolean showPermission,
            @RequestParam(value = "roleId", required = false) Long roleId, @RequestParam(value = "filterMenuId", required = false) Long filterMenuId) {
        return getNodeList(showPermission, roleId, filterMenuId);
    }

    @RequestMapping(value = {"getTreeWithRoot"}, method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public JsTreeBean getTreeWithRoot(@RequestParam(value = "showPermission", required = false) boolean showPermission,
            @RequestParam(value = "roleId", required = false) Long roleId, @RequestParam(value = "filterMenuId", required = false) Long filterMenuId) {
        List<JsTreeBean> nodeList = getNodeList(showPermission, roleId, filterMenuId);

        JsTreeBean root = new JsTreeBean();
        root.setId(JsTreeBean.ROOT_NODE_ID);
        root.setText("菜单树");
        root.getState().setOpened(true);

        root.setChildren(nodeList);

        return root;
    }

    /**
     * 校验是否可删除
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = {"{id}/validate"}, method = RequestMethod.GET)
    @ResponseBody
    public Map<String, String> validate(@PathVariable("id") Long id) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("result", "true");
        Menu menu = menuRepository.findOne(id);
        // 是否拥有子菜单, 如果有则不能删除
        List<Menu> menus = menuRepository.findByParentId(id);
        if (null != menus && !menus.isEmpty()) {
            map.put("result", "false");
            map.put("description", "[" + menu.getName() + "]菜单拥有子节点,无法删除!");
        }
        return map;
    }

    @RequestMapping(value = {"{id}/findChild"}, method = RequestMethod.GET)
    @ResponseBody
    public List<Menu> findChild(@PathVariable("id") Long id) {
        List<Menu> menuList = menuRepository.findByParentId(id);
        return menuList;
    }

}
